package com.xw.unification.entity;

import com.xw.unification.annotations.SignatureCheckDefinition;
import com.xw.unification.config.WebUnificationMvcProperties.SignatureCheckProperties;
import com.xw.unification.enums.SignatureOperation;
import com.xw.unification.enums.SortType;
import com.xw.unification.helper.StringHelper;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Getter
public class SignatureCheckContext {

    private SignatureCheckProperties properties;
    private boolean hasSignatureKey;
    private boolean signatureKeyInSort;
    private String signatureKeyName;
    @Setter
    private String signatureKeyValue;
    private String validationSignatureName;
    private boolean ignoreEmptyValue;
    private String checkErrorEnumName;
    private SortType paramNameSort;
    private final String charsetName;
    private final List<SignatureOperation> operations = new ArrayList<>();
    private final List<String> ignoreParamNames = new ArrayList<>();
    @Setter
    private String validation;

    public SignatureCheckContext(SignatureCheckProperties properties) {
        if (properties == null) {
            throw new IllegalArgumentException("SignatureCheckProperties can not be null");
        }
        this.properties = properties;
        charsetName = properties.getCharsetName();
        hasSignatureKey = properties.isHasSignatureKey();
        signatureKeyInSort = properties.isSignatureKeyInSort();
        signatureKeyName = properties.getSignatureKeyName();
        validationSignatureName = properties.getValidationSignatureName();
        ignoreEmptyValue = properties.isIgnoreEmptyValue();
        checkErrorEnumName = properties.getCheckErrorEnumName();
        paramNameSort = properties.getParamNameSort();
        operations.clear();
        if (properties.getSignatureOperations() != null) {
            operations.addAll(properties.getSignatureOperations());
        }
    }

    public SignatureCheckContext combineSignatureCheckAnnotation(SignatureCheckDefinition anno) {
        if (anno != null) {
            hasSignatureKey = anno.hasSignatureKey();
            signatureKeyInSort = anno.signatureKeyInSort();
            signatureKeyName = anno.signatureKeyName();
            validationSignatureName = anno.validationSignatureName();
            ignoreEmptyValue = anno.ignoreEmptyValue();
            checkErrorEnumName = anno.checkErrorEnumName();
            paramNameSort = anno.paramNameSort();
            String[] strings = anno.ignoreParamNames();
            if (strings != null && strings.length > 0) {
                ignoreParamNames.clear();
                ignoreParamNames.addAll(Arrays.stream(strings).filter(StringHelper::hasText)
                        .collect(Collectors.toList()));
            }
            operations.clear();
            if (anno.operations() != null) {
                operations.addAll(Arrays.asList(anno.operations()));
            }
        }
        return this;
    }

}
